package com.zz.util;

import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

public class CertUtil {
	/**
	 * 获取X509证书对象
	 * @param pfxByte
	 * @param passWord
	 * @return
	 * @throws Exception
	 */
	public static X509Certificate getCertificateByPfx(byte[] pfxByte,String passWord)  throws Exception{
		KeyStore objKs = getKeyStoreByPfx(pfxByte,passWord);
		Enumeration<String> objEnum = objKs.aliases();
		String aliasesName = "";
		while (objEnum.hasMoreElements()) {
			aliasesName = (String) objEnum.nextElement();
		}
		Certificate certificate = objKs.getCertificate(aliasesName);
		X509Certificate x509Cert = (X509Certificate) certificate;
		return x509Cert;
	}
	
	/**
	 * 获取证书链
	 * @param keyStore
	 * @return
	 * @throws Exception
	 */
	public static Certificate[] getCertificateChainByKeyStore(KeyStore keyStore) throws Exception{
		Enumeration<String> objEnum = keyStore.aliases();
		String aliasesName = "";
		while (objEnum.hasMoreElements()) {
			aliasesName = (String) objEnum.nextElement();
		}
		Certificate[] cf = keyStore.getCertificateChain(aliasesName);
		return cf;
	}
	
	/**
	 * 获取KeyStore
	 * @param pfxByte
	 * @param passWord
	 * @return
	 * @throws java.security.KeyStoreException
	 * @throws java.security.NoSuchAlgorithmException
	 * @throws java.security.cert.CertificateException
	 */
	public static KeyStore getKeyStoreByPfx(byte[] pfxByte,String passWord) throws Exception{
		KeyStore objKs = KeyStore.getInstance("PKCS12");
		try {
			objKs.load(new ByteInputStream(pfxByte,pfxByte.length), passWord.toCharArray());
		} catch (IOException e) {
			throw new Exception("证书密码错误。");
		}
		return objKs;
	}

	/**
	 * 获取私钥
	 * @param objKs
	 * @param passWord
	 * @return
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKeyByKeyStore(KeyStore objKs,String passWord)  throws Exception{
		Enumeration<String> objEnum = objKs.aliases();
		String aliasesName = "";
		while (objEnum.hasMoreElements()) {
			aliasesName = (String) objEnum.nextElement();
		}
		PrivateKey key = (PrivateKey)objKs.getKey(aliasesName, passWord.toCharArray());
		return key;
	}

	/**
	 * 从pfx文件获取私钥
	 * @param pfxByte
	 * @param passWord
	 * @return
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKeyByPfx(byte[] pfxByte,String passWord)  throws Exception{
		KeyStore objKs = getKeyStoreByPfx(pfxByte,passWord);
		Enumeration<String> objEnum = objKs.aliases();
		String aliasesName = "";
		while (objEnum.hasMoreElements()) {
			aliasesName = (String) objEnum.nextElement();
		}
		PrivateKey key = (PrivateKey)objKs.getKey(aliasesName, passWord.toCharArray());
		return key;
	}

	/**
	 * 私钥加密
	 * @param key
	 * @param data
	 * @return
	 * @throws java.security.NoSuchAlgorithmException
	 * @throws javax.crypto.NoSuchPaddingException
	 * @throws java.security.InvalidKeyException
	 * @throws javax.crypto.IllegalBlockSizeException
	 * @throws javax.crypto.BadPaddingException
	 */
	public static byte[] encryptByPrivateKey(PrivateKey key,byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		Cipher cipher = Cipher.getInstance(key.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(data);
	}

	/**
	 * 私钥解密
	 * @param key
	 * @param data
	 * @return
	 * @throws java.security.NoSuchAlgorithmException
	 * @throws javax.crypto.NoSuchPaddingException
	 * @throws java.security.InvalidKeyException
	 * @throws javax.crypto.IllegalBlockSizeException
	 * @throws javax.crypto.BadPaddingException
	 */
	public static byte[] decryptByPrivateKey(PrivateKey key,byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		Cipher cipher = Cipher.getInstance(key.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, key);
		return cipher.doFinal(data);
	}

	/**
	 * 获取公钥
	 * @param cert
	 * @return
	 */
	public static PublicKey getPublicKeyByCert(X509Certificate cert){
		PublicKey publicKey = cert.getPublicKey();
		return publicKey;
	}

	/**
	 * 公钥加密
	 * @param key
	 * @param data
	 * @return
	 * @throws java.security.NoSuchAlgorithmException
	 * @throws javax.crypto.NoSuchPaddingException
	 * @throws java.security.InvalidKeyException
	 * @throws javax.crypto.IllegalBlockSizeException
	 * @throws javax.crypto.BadPaddingException
	 */
	public static byte[] encryptByPublicKey(PublicKey key,byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		Cipher cipher = Cipher.getInstance(key.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, key);
		return cipher.doFinal(data);
	}

	/**
	 * 公钥解密
	 * @param key
	 * @param data
	 * @return
	 * @throws java.security.NoSuchAlgorithmException
	 * @throws javax.crypto.NoSuchPaddingException
	 * @throws java.security.InvalidKeyException
	 * @throws javax.crypto.IllegalBlockSizeException
	 * @throws javax.crypto.BadPaddingException
	 */
	public static byte[] decryptByPublicKey(PublicKey key,byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		Cipher cipher = Cipher.getInstance(key.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, key);
		return cipher.doFinal(data);
	}

	/**
	 * 获取签名对象
	 * @param cert
	 * @param pkey
	 * @return
	 * @throws java.security.NoSuchAlgorithmException
	 */
	public static Signature getSignatureObj(X509Certificate cert,PrivateKey pkey) throws NoSuchAlgorithmException{
		Signature signObj = Signature.getInstance(cert.getSigAlgName());
		return signObj;
	}

	/**
	 * 签名
	 * @param sigAlgName
	 * @param key
	 * @param sign
	 * @return
	 * @throws java.security.NoSuchAlgorithmException
	 * @throws java.security.InvalidKeyException
	 * @throws java.security.SignatureException
	 */
	public static byte[] sign(String sigAlgName,PrivateKey key,byte[] sign) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException{
		Signature signature = Signature.getInstance(sigAlgName);
		signature.initSign(key);
		signature.update(sign);
		return signature.sign();
	}

	/**
	 * 签名验证
	 * @param cert
	 * @param data
	 * @param sign
	 * @return
	 * @throws java.security.NoSuchAlgorithmException
	 * @throws java.security.InvalidKeyException
	 * @throws java.security.SignatureException
	 */
	public static boolean verify(X509Certificate cert,byte[] data,byte[] sign) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException{
		Signature signature = Signature.getInstance(cert.getSigAlgName());
		signature.initVerify(cert);
		signature.update(data);
		return signature.verify(sign);
	}
	
	/**
	 * 获取X509证书对象
	 * @param certByte
	 * @return
	 * @throws Exception
	 */
	public static X509Certificate getCertificateByCertFile(byte[] certByte) throws Exception{
		CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
		Certificate certificate = certificateFactory.generateCertificate(new ByteInputStream(certByte,certByte.length));
		X509Certificate x509Cert = (X509Certificate) certificate;
		return x509Cert;
	}
	
	

	
	public static void main(String[] args) {
		boolean dd = "".startsWith(".");
		//System.out.println(dd);
	}
}
